package com.hanock.sm.fork2d;


import java.util.HashSet;
import java.util.Set;

import javax.microedition.khronos.opengles.GL10;


import android.content.Context;
import android.graphics.Bitmap.Config;
import android.graphics.Paint.Align;



public class TextureManager {

	private static TextureManager instance = null;

	public static TextureManager createInstance(Context context){
		instance = new TextureManager(context);
		return instance;
	}
	
	public static TextureManager getInstance(){
		return instance;
	}
	
	
	
	// ---------------------------------------------------------------------------------------------------
	
	private Set<Texture> textureSet;
	private SparseArray<Texture> resTextureMap;
	
	private Set<Integer> maintainResSet;
	private SparseArray<Config> configMap;
	
	private Context context;
	private GL10 gl;

	
	
	private TextureManager(Context context) {
		this.context = context;
		
		textureSet = new HashSet<Texture>();
		resTextureMap = new SparseArray<Texture>();
		maintainResSet = new HashSet<Integer>();
		configMap = new SparseArray<Config>();
	}
	
	public Texture loadTest(int resId){
		Texture tex = TextureUtil.createTexture(gl, context, resId);
		textureSet.add(tex);
		return tex;
	}
	
	public Texture load(int resId){
		Texture tex = resTextureMap.get(resId);

		if (tex == null){
			Config config = configMap.get(resId);
			if (config == null)
				tex = TextureUtil.createTexture(gl, context, resId);
			else{
				tex = TextureUtil.createTexture(gl, context, resId, config);
			}
				
			if (tex != null){
				resTextureMap.put(resId, tex);
				//Log.i("test2", "load: " + Integer.toHexString(resId));
			}
			return tex;
		}
		else
			return tex;
	}
	
	public Texture load(String text, float fontSize){
		return load(text, fontSize, Align.LEFT);
	}
	
	public Texture load(String text, float fontSize, Align align){
		Texture texture = TextureUtil.createTexture(gl, text, fontSize, align);
		textureSet.add(texture);
		return texture;
	}

	public void releaseDisposables(){
		for (Texture texture: textureSet){
			TextureUtil.deleteTexture(gl, texture);
		}
		
		textureSet.clear();
	}
	
	public void releaseAll(){
		
		for (Texture texture: textureSet){
			TextureUtil.deleteTexture(gl, texture);
		}
		
		for (Object obj: resTextureMap.values()){
			if (obj == null)
				continue;
			TextureUtil.deleteTexture(gl, (Texture)obj);
		}
		
		textureSet.clear();
		resTextureMap.clear();
	}
	
	public void release(int resId){
		if (resTextureMap.get(resId) != null){
			TextureUtil.deleteTexture(gl, resTextureMap.get(resId));
			resTextureMap.remove(resId);
			
			//Log.i("test2", "release: " + Integer.toHexString(resId));
		}
	}
	
	public void release(Texture texture){
		if (textureSet.contains(texture)){
			TextureUtil.deleteTexture(gl, texture);
			textureSet.remove(texture);
		}
	}
	
	public void addMaintain(int resId){
		maintainResSet.add(resId);
	}
	
	public void loadMaintain(){
		for (int resId: maintainResSet){
			load(resId);
			
		}
	}
	
	public void clearMaintain(){
		maintainResSet.clear();
	}
	
	public void putConfig(int resId, Config config){
		configMap.put(resId, config);
	}
	
	public void clearConfig(){
		configMap.clear();
	}
	
	public boolean has(int resId){
		return resTextureMap.get(resId) != null;
	}
	
	public boolean has(Texture texture){
		return textureSet.contains(texture);
	}
	
	public void onSurfaceCreated(GL10 gl){
		resTextureMap.clear();
		textureSet.clear();
		this.gl = gl;
		
		loadMaintain();
	}

}






























